# abcd
# Tim Menzies
# Nov 2 2013
 
function abcd(actual,predicted,_ABCD,    k) {
  abcd0(actual,   _ABCD)
  abcd0(predicted,_ABCD)
  if(actual==predicted) { yn[1]++ } else { yn[0]++ }
  for(k in class)  
    if (actual==k) { 
      predicted==actual ? d[k]++ : b[k]++
    } else { 
      predicted==k      ? c[k]++ : a[k]++ }
}    
function abcd0(k,_ABCD) {
  yn[1] += 0; yn[0] += 0; a[k] += 0; b[k] += 0; c[k] += 0; d[k] += 0;
  if (++class[k]==1)  # first time we have seen this so all prior
    a[k] = yn[1] + yn[0]  # results are not(k) being classified not(k)
}
function reports_ABCD(_ABCD,skip,   k,com) {
  com = "sort -t, -n -k 11"
  print "\n#" db
  print "#n,a,b,c,d,acc,pd,prec,pf,f,g,pn,klass,"rx0 
  for(k in class)
    if (k != skip) 
      report_ABCD(k,_ABCD,com)
  close(com)
}
function accuracy(_ABCD) { 
  return yn[1] / (yn[0] + yn[1]) 
}
function report_ABCD(k,_ABCD,com,   acc,pd,pf,prec,f,g,pn) {
  acc = pd = pf = prec = f = g = pn = 0
  if (b[k] + d[k])  pd   = d[k]         / (b[k] + d[k])
  if (a[k] + c[k])  pf   = c[k]         / (a[k] + c[k])
  if (a[k] + c[k])  pn   = (b[k]+d[k])  / (a[k] + c[k])
  if (c[k] + d[k])  prec = d[k]         / (c[k] + d[k])
  if (1-pf+pd    )  g    = 2*(1-pf)*pd  / (1-pf+pd)
  if (prec+pd    )  f    = 2*prec*pd    / (prec+pd)
  if (yn[1]+yn[0])  acc  = yn[1]        / (yn[1]+yn[0])
  print (yn[1]+yn[0]),a[k],b[k],c[k],d[k],p(acc),  \
    p(pd),p(prec),p(pf),p(f),p(g),			\
    sprintf("%.2f",pn),k,rx | com
}

